package com.yunji.order.context.convert;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableTable;
import com.yunji.order.dto.OrderVisualDTO;
import com.yunji.order.dto.OrderVisualDetailDTO;
import com.yunji.common.constant.Constants;
import com.yunji.common.utils.Pair;
import com.yunji.common.utils.bean.BeanUtils;
import com.yunji.coupon.dto.OrderAmtDTO;
import com.yunji.coupon.dto.OrderScaleDTO;
import com.yunji.order.bo.OrderUnFrozenBO;
import com.yunji.order.context.builder.OrderDetailBuilder;
import com.yunji.order.domain.OrderDO;
import com.yunji.order.domain.OrderDetailDO;
import com.yunji.order.domain.OrderScaleDO;
import com.yunji.order.dto.OrderDetailRefundDTO;
import com.yunji.order.dto.cmd.OrderCreateCommandDTO;
import com.yunji.order.emuns.OrderStatusEnum;
import com.yunji.order.service.OrderService;
import com.yunji.order.vo.OrderDetailVO;
import com.yunji.order.vo.OrderVO;
import org.apache.commons.compress.utils.Lists;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author : peter-zhu
 * @date : 2024/11/30 13:41
 * @description : TODO
 **/
public class OrderConvert {

    public static OrderUnFrozenBO buildOrderScaleBO(OrderDO order) {
        return new OrderUnFrozenBO(order.getOrderId(), order.getOrderStatus(), order.getSiteId(),
                order.getAgentId(), order.getFrozen());
    }

    /**
     * @param : phone
     * @return : java.lang.String
     * @author : peter-zhu
     * @date : 2024/12/18 14:59
     * @description : 订单的用户手机号脱敏
     */
    public static String encryptMemberPhone(String phone) {
        if (BeanUtils.isNotNull(phone) && phone.length() == 11) {
            return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
        }
        return phone;
    }

    public static List<OrderDetailDO> convert2DetailDO(List<OrderAmtDTO> list) {
        Collection<OrderAmtDTO> values = list.stream()
                .collect(Collectors.toMap(
                        dto -> dto.getProductCacheDTO().getId(),
                        dto -> dto,
                        OrderAmtDTO::add
                )).values();
        List<OrderDetailDO> orderDetailDOList = Lists.newArrayList();
        for (OrderAmtDTO dto : values) {
            orderDetailDOList.add(OrderDetailBuilder.builder().buildAmount(dto).buildProduct(dto.getProductCacheDTO()).build());
        }
        return orderDetailDOList;
    }

    public static OrderVO domain2VO(OrderDO orderDO, List<OrderDetailDO> orderDetailDOList,
                                    List<OrderDetailRefundDTO> refundNumDTOs) {
        ImmutableTable<String, Long, List<Pair<Integer, Integer>>> refundNums = RefundConvert.buildTableNums(refundNumDTOs);
        OrderVO orderVO = new OrderVO();
        BeanUtils.clone(orderDO, orderVO);
        orderVO.setOrderStatusDesc(OrderStatusEnum.get(orderVO.getOrderStatus()));
        orderVO.setDetailList(detailDO2VO(orderDetailDOList));
        setDetailsNums(orderVO.getOrderCode(), orderVO.getDetailList(), refundNums);
        ImmutableMap<Long, List<Pair<Integer, Integer>>> row = refundNums.row(orderVO.getOrderCode());
        if (row != null)
            orderVO.setRefundStatusNums(row.values().stream()
                    .flatMap(List::stream) // 将多个 List<Pair> 合并成一个流
                    .collect(Collectors.toList()));
        return orderVO;
    }

    public static void setDetailsNums(String orderCode, List<OrderDetailVO> orderDetailDOList, List<OrderDetailRefundDTO> refundNumDTOs) {
        setDetailsNums(orderCode, orderDetailDOList, RefundConvert.buildTableNums(refundNumDTOs));
    }

    public static void setDetailsNums(String orderCode, List<OrderDetailVO> orderDetailDOList,
                                      ImmutableTable<String, Long, List<Pair<Integer, Integer>>> refundNums) {
        for (OrderDetailVO detail : orderDetailDOList) {
            detail.setRefundStatusNums(refundNums.get(orderCode, detail.getOrderDetailId()));
        }
    }

    public static List<OrderVO> domains2VOs(List<OrderDO> orderDOS, OrderService orderService,
                                            List<OrderDetailRefundDTO> refundNumDTOs) {
        List<Long> orderIds = orderDOS.stream().map(OrderDO::getOrderId).collect(Collectors.toList());
        Map<Long, List<OrderDetailDO>> detailListMap = orderService.getDetailListMapByOds(orderIds);
        List<OrderVO> orderVOList = Lists.newArrayList();
        for (OrderDO domain : orderDOS) {
            OrderVO orderVO = domain2VO(domain, detailListMap.get(domain.getOrderId()), refundNumDTOs);
            orderVOList.add(orderVO);
        }
        return orderVOList;
    }

    public static List<OrderDetailVO> detailDO2VO(List<OrderDetailDO> domains) {
        return domains.stream().map(OrderConvert::detailDO2VO).collect(Collectors.toList());
    }

    public static OrderDetailVO detailDO2VO(OrderDetailDO domain) {
        OrderDetailVO detailVO = new OrderDetailVO();
        BeanUtils.clone(domain, detailVO);
        return detailVO;
    }

    public static OrderScaleDO convertScaleDetail(OrderScaleDTO sc) {
        OrderScaleDO sale = new OrderScaleDO();
        sale.setAgentMode(sc.getAgentMode());
        sale.setTradeType(sc.getTradeType());
        sale.setScaleAmount(sc.getAmt());
        sale.setBalance(sc.getBalance());
        sale.setAccountId(sc.getAccountId());
        sale.setBelongId(sc.getAccountId());
        sale.setAccountType(sc.getAccountType());
        sale.setAccountName(sc.getAccountName());
        sale.setAccountTel(sc.getAccountTel());
        sale.setAccountScaleRatio(sc.getScale());
        sale.setAccountScaleType(sc.getScaleType());
        return sale;
    }

    /**
     * @param : list
     * @return : java.util.List<com.yunji.order.domain.Order>
     * @author : peter-zhu
     * @date : 2024/12/18 15:00
     * @description : 订单的用户手机号脱敏 支持数组 并帮判断非管理员才脱敏
     */
//    public static List<OrderDO> convertByNotAdmin(List<OrderDO> list) {
//        if (!SystemContext.isPlate()) {
//            for (OrderDO order : list) {
//                order.setMemberPhone(encryptMemberPhone(order.getMemberPhone()));
//            }
//        }
//        return list;
//    }

    public static OrderVisualDTO convertQueueDTO(OrderDO order,List<OrderDetailDO> detailList) {
        OrderVisualDTO orderVisualDTO = new OrderVisualDTO();
        BeanUtils.clone(order, orderVisualDTO);
        List<OrderVisualDetailDTO> dtoList = new ArrayList<>();
        for (OrderDetailDO orderDetailDO : detailList) {
            OrderVisualDetailDTO dto = new OrderVisualDetailDTO();
            BeanUtils.clone(orderDetailDO, dto);
            dtoList.add(dto);
        }
        orderVisualDTO.setDetailList(dtoList);
        orderVisualDTO.setSystemCode(Constants.SYSTEM_NAME);
        return orderVisualDTO;
    }

}
